import { exec } from 'child_process'
import * as path from 'path'
import * as util from 'util'
import { Client } from 'ssh2'

const execPromise = util.promisify(exec)

// ================== 配置 ==================
const PM2_APP_NAME = 'dxservice'
const REMOTE_USER = 'root'
const REMOTE_HOST = '172.81.211.63'
const REMOTE_PORT = 22999
const REMOTE_PATH = `/data/nginx/${PM2_APP_NAME}`
const LOCAL_PROJECT_PATH = path.resolve(__dirname, '../')
const FILES_TO_UPLOAD = ['dist', 'package.json', '.env.production']
const BUILD_COMMAND = 'npm run build'
// =========================================

async function buildCommand() {
  console.log('🛠️ [1/3] 正在构建项目...')
  await execPromise(BUILD_COMMAND, { cwd: LOCAL_PROJECT_PATH })
  console.log('✅ Build 执行完成\n')
  console.log('✅ 构建完成\n')
}

async function uploadFiles() {
  console.log('🚀 [2/3] 上传文件中...')

  // 确保远程目录存在
  const mkdirCommand = `ssh ${REMOTE_USER}@${REMOTE_HOST} -p ${REMOTE_PORT} "mkdir -p ${REMOTE_PATH}"`
  await execPromise(mkdirCommand)

  const uploadPromises = FILES_TO_UPLOAD.map(async (item) => {
    const sourcePath = path.join(LOCAL_PROJECT_PATH, item)
    const targetPath = `${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/`
    console.log(`📂 上传 ${item} -> ${targetPath}`)
    // await execPromise(`rsync -avz --delete ${sourcePath} ${targetPath}`);
    await execPromise(`scp -P ${REMOTE_PORT} -r ${sourcePath} ${targetPath}`)
  })

  await Promise.all(uploadPromises)

  console.log('✅ 文件上传完成\n')
}

async function reloadPm2() {
  return new Promise((resolve, reject) => {
    const conn = new Client()

    conn.on('ready', () => {
      console.log('🔌 SSH 已连接，准备执行 pm2 reload...')

      conn.shell((err, stream) => {
        if (err)
          return reject(err)

        let output = ''

        stream.on('data', (data) => {
          output += data.toString()
          process.stdout.write(data.toString())
        })

        stream.on('close', () => {
          console.log('🔚 SSH 命令执行结束')
          conn.end()
          resolve(output)
        })

        stream.write(`pm2 reload all\n`)
        stream.write(`exit\n`)
      })
    })

    conn.on('error', reject)

    conn.connect({
      host: REMOTE_HOST,
      port: REMOTE_PORT,
      username: REMOTE_USER,
      password: 'P4B2pD4h73fFV6W8',
    })
  })
}

async function main() {
  console.log('====== 📤 开始部署任务 ======\n')

  await buildCommand()
  await uploadFiles()
  await new Promise(resolve => setTimeout(resolve, 2000))
  await reloadPm2()
  console.log(new Date().toLocaleString('zh-cn'), '\n')
}

main()
